#pragma once
// OpenGL and GLEW Header Files and Libraries
#include <GL/glew.h>
#include <GL/wglew.h>
#include <GL/glfw.h>
#include <vector>
#include <map>
#include <string>
#include <iostream>

#pragma comment(lib, "glew32.lib")
#pragma comment(lib, "opengl32.lib")

#include <glm/glm.hpp>
#include <glm/gtx/matrix_operation.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/half_float.hpp>

extern "C" {
	#include <lua.h>
	#include <lauxlib.h>
	#include <lualib.h>
}

//Kinect Support

#include <KinectWinLibCmn.h>
#include <KinectWinMgr.h>
#include <KinectWinGesture.h>




extern float nearPlane, farPlane, fov;

struct BoundingBox
{
	glm::vec3 max;
	glm::vec3 min;
};

struct Light {
	glm::vec3 lightsPos;
	glm::vec3 lightsCol;
	float lightsIntensivity;
	bool alive;
};

struct Entity {

	
	glm::vec3 position;
	glm::vec3 rotation;
	glm::vec3 scale;
	std::string modelUsed;
	bool alive;
	BoundingBox box;
	bool selected;
};

struct Scene {
	std::map<int, Entity> entities;
	std::map<int, Light> lights;
};

extern int uScrWidth;
extern int uScrHeight;


GLuint loadTGA_glfw(const char * imagepath);

GLuint LoadProgram(const char* vs, const char* fs);

struct ProgramHandles {
	GLuint Main;
	GLuint BoundingBoxes;
};




/*
	Meshes stuff
*/
struct Material {
	GLuint AmbientTexture;
	GLuint DifuseTexture;
	GLuint NormalTexture;
	GLuint SpecularTexture;
	

	//GLuint texture;
	//GLuint normalTexture;
	
	std::string  name;
	glm::vec3 AmbiantColor;
	glm::vec3 DifuseColor;
	glm::vec3 SpecularColor;
	float Shinies;
};



struct subMesh {
	std::vector<glm::vec3> vertices, normals;
	std::vector<glm::vec2> uvs;
	Material material;
};

struct Mesh {
	std::map<std::string, subMesh> subMeshes; 
};

struct ShaderUniforms {
	GLuint MVP;
	GLuint V;
	GLuint M;
	GLuint MV3x3;

	GLuint AmbientTextureSampler;
	GLuint DiffuseTextureSampler;
	GLuint NormalTextureSampler;
	GLuint SpecularTextureSampler;

	GLuint AmbientColor;
	GLuint DifuseColor;
	GLuint SpecularColor;
	GLuint Shines;

	GLuint NoLights; // need to improve that
	GLuint LightPosition;
	GLuint LightPower;
	GLuint LightColor;

};
struct BoundingUniform {
	GLuint MVP;
	GLuint V;
	GLuint M;
};
/*
Drawing 2D text
*/
void initText2D(const char * texturePath);
void printText2D(const char * text, int x, int y, int size);
void cleanupText2D();

/*debuger */
extern void initDebuger();
extern void renderLightsDebug(std::map<int, Light> lights, glm::mat4 MVP);



